'use strict';
// Copyright 2014 Blueant Inc. All Rights Reserved.

/**
 * @fileoverview 判断该地图是否所有建筑都有效
 * @author sundbcn@gmail.com (sun debing)
 */

var _ = require('lodash');

// 入口格子位置
var BEGIN_CELL = 36;

// 终点格子位置
var END_CELL = 42;

// 地图的大小
var ROAD_SIZE_WIDTH = 9;
var ROAD_SIZE_HEIGH = 9;

// 固定开放路快
var NEXUS_BESIDE_CELL_LIST = [34, 35, 43, 44, 52, 53];

// 在起点处不能建造的格子
var INVALID_CELL_LIST = [];

// 固定不能建造路块
var BUILD_NOT_CELL_LIST = [27, 28, 36, 37, 45, 46];

/**
 * 验证地图数据是否有效
 * @param  {[type]}  build_list [description]
 * @param  {[type]}  road_list  [description]
 */
exports.isValid = function (build_list, block_list, road_list, ruin_list) {
    // 判断是否碰撞

    if (!_checkCollision(build_list, road_list, ruin_list)) {
        return false;
    }

    // 判断路障是否有碰撞
    if (!_checkCollisionBlock(block_list)) {
        return false;
    }

    // 判断第一个值是否是入口
    // 判断最后一个值是否是出口
    // 判断路是否连通
    if (!_checkRoad(road_list)) {
        return false;
    }

    // 所有建筑旁边至少有一个桥连着.
    if (!_checkBuildBesideRoad(build_list, road_list)) {
        return false;
    }

    // 固定路块不能造塔
    if (!_fixedRoadNotCell(build_list)) {
        return false;
    }
    return true;
    // 判断路障是否在路上  已经没有路障
    // return _checkBlockInRoad(block_list, road_list);
};

/**
 * 固定路块不能有建筑
 * @param  {[type]} block_list [description]
 * @return {[type]}            [description]
 */
var _fixedRoadNotCell = function (build_list) {
    var is_valid = true;
    _.some(build_list, function (build_cell) {
        if (_.indexOf(BUILD_NOT_CELL_LIST, build_cell) !== -1) {
            is_valid = false;
            return true;
        }
    });
    return is_valid;
};

/**
 * 判断建筑之间是否有碰撞
 * @param  {[type]} build_list [description]
 * @param  {[type]} road_list  [description]
 * @return {[type]}            [description]
 */
var _checkCollision = function (build_list, road_list, ruin_list) {
    var all_cell_count = {};

    _.each(build_list, function (cell) {
        all_cell_count[cell] = all_cell_count[cell] || 0;
        all_cell_count[cell]++;
    });

    _.each(road_list, function (cell) {
        all_cell_count[cell] = all_cell_count[cell] || 0;
        all_cell_count[cell]++;
    });

    _.each(ruin_list, function (cell) {
        all_cell_count[cell] = all_cell_count[cell] || 0;
        all_cell_count[cell]++;
    });

    _.each(INVALID_CELL_LIST, function (cell) {
        all_cell_count[cell] = all_cell_count[cell] || 0;
        all_cell_count[cell]++;

    });

    var is_valid = true;
    _.some(all_cell_count, function (cell_count) {
        if (cell_count > 1) {
            is_valid = false;
            return true;
        }
    });
    return is_valid;
};

/**
 * 判断路障之间是否有碰撞
 * @param  {[type]} block_list [description]
 * @return {[type]}            [description]
 */
var _checkCollisionBlock = function (block_list) {
    var all_cell_count = {};

    _.each(block_list, function (cell) {
        all_cell_count[cell] = all_cell_count[cell] || 0;
        all_cell_count[cell]++;
    });

    var is_valid = true;
    _.some(all_cell_count, function (cell_count) {
        if (cell_count > 1) {
            is_valid = false;
            return true;
        }
    });
    return is_valid;
};

/**
 * 判断所有的路是否有接着其他的路
 * @param  {[type]} road_list [description]
 * @return {[type]}                [description]
 */
var _checkRoad = function (road_list) {
    if (_.first(road_list) != BEGIN_CELL ||
        _.last(road_list) != END_CELL) {
        return false;
    }

    for (var i = 0; i < road_list.length - 1; i++) {
        if (!_checkRoadBesideRoad(road_list[i], road_list[i + 1])) {
            return false;
        }
    }

    return true;
};

/**
 * 判断所有的建筑是否有接着路
 * @param  {[type]} build_list [description]
 * @param  {[type]} road_list  [description]
 * @return {[type]}                 [description]
 */
var _checkBuildBesideRoad = function (build_list, road_list) {
    var is_build_valid = true;
    _.some(build_list, function (cell) {
        if (!_checkBesideRoad(cell, road_list)) {
            is_build_valid = false;
            return true;
        }
    });
    return !!is_build_valid;
};

/**
 * 判断路障是否在路上
 * @param  {[type]} block_list [description]
 * @param  {[type]} road_list  [description]
 * @return {[type]}            [description]
 */
var _checkBlockInRoad = function (block_list, road_list) {
    var is_valid = true;
    _.some(block_list, function (block_cell) {
        if (_checkInRoad(block_cell, road_list) === false) {
            is_valid = false;
            return true;
        }
    });
    return is_valid;
};

/**
 * 判断一个建筑cell是否靠着路
 * @param  {[type]} build_cell           [description]
 * @param  {[type]} road_list [description]
 * @return {[type]}                [description]
 */
var _checkBesideRoad = function (build_cell, road_list) {
    // 判断建筑是否在路旁边
    var beside_cell_list = _getCellBesideList(build_cell);
    if (_.intersection(beside_cell_list, road_list).length > 0) {
        return true;
    }

    // 判断建筑是否加在固定路块旁边
    if (_.intersection(beside_cell_list, NEXUS_BESIDE_CELL_LIST).length > 0) {
        return true;
    }
    // return _.indexOf(NEXUS_BESIDE_CELL_LIST, build_cell) != -1;
};

/**
 * 格子是否在路上
 * @param  {[type]} build_cell [description]
 * @param  {[type]} road_list  [description]
 * @return {[type]}            [description]
 */
var _checkInRoad = function (build_cell, road_list) {
    return _.indexOf(road_list, build_cell) != -1;
};

/**
 * 判断路是否和另一个路连接着
 * @param  {[type]} road_cell1 [description]
 * @param  {[type]} road_cell2 [description]
 * @return {[type]}            [description]
 */
var _checkRoadBesideRoad = function (road_cell1, road_cell2) {
    var beside_cell_list = _getCellBesideList(road_cell1);

    var is_exist_road = false;
    _.some(beside_cell_list, function (beside_cell) {
        if (beside_cell == road_cell2) {
            is_exist_road = true;
            return true;
        }
    });

    return is_exist_road;
};

/**
 * 获取一个元素的旁边4个元素
 * @param  {[type]} cell [description]
 * @return {[type]}      [description]
 */
var _getCellBesideList = function (cell) {
    var x = cell % ROAD_SIZE_HEIGH;
    var y = parseInt(cell / ROAD_SIZE_HEIGH);
    var beside_cell_list = [];
    if (x - 1 >= 0) {
        beside_cell_list.push((x - 1) + y * ROAD_SIZE_HEIGH);
    }
    if (x + 1 < ROAD_SIZE_HEIGH) {
        beside_cell_list.push((x + 1) + y * ROAD_SIZE_HEIGH);
    }
    if (y - 1 >= 0) {
        beside_cell_list.push(x + (y - 1) * ROAD_SIZE_HEIGH);
    }
    if (y + 1 < ROAD_SIZE_WIDTH) {
        beside_cell_list.push(x + (y + 1) * ROAD_SIZE_HEIGH);
    }
    return beside_cell_list;
};

// var _getCellBesideList = function (cell) {
//     cell--;
//     var x = cell % ROAD_SIZE_HEIGH;
//     var y = parseInt(cell / ROAD_SIZE_HEIGH);
//     var beside_cell_list = [];
//     if (x - 1 >= 0) {
//         beside_cell_list.push((x - 1) + y * ROAD_SIZE_HEIGH + 1);
//     }
//     if (x + 1 < ROAD_SIZE_HEIGH) {
//         beside_cell_list.push((x + 1) + y * ROAD_SIZE_HEIGH + 1);
//     }
//     if (y - 1 >= 0) {
//         beside_cell_list.push(x + (y - 1) * ROAD_SIZE_HEIGH + 1);
//     }
//     if (y + 1 < ROAD_SIZE_WIDTH) {
//         beside_cell_list.push(x + (y + 1) * ROAD_SIZE_HEIGH + 1);
//     }
//     return beside_cell_list;
// };
